﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace Tank
{
    public class Screen : Scene
    {
        protected Dictionary<string, string> textureList;
        protected bool sceneOver;
        protected int width;
        protected int height;

        //EMPTY CONSTRUCTOR
        public Screen(int _width, int _height)
        {
            textureList = new Dictionary<string, string>();
            sceneOver = false;

            int width = _width;
            int height = _height;
        }

        //ADD TEXTURE
        public virtual void AddTexture(string key, string textureID)
        {
           textureList[key] = textureID;
        }

        //DRAW
        public virtual void Draw(SpriteBatch sb)
        {
           Vector2 origin = new Vector2(0, 0);
           Debug.Assert(textureList["background"] != null);
           Texture2D texture = World.Instance.GetTexture(textureList["background"]);   //returns the name of the Texture2D Object
           sb.Draw(texture, origin, Color.White);
        }

        //UPDATE
        public virtual void Update(float deltaTime)
        {
            if (sceneOver)
                return;

            // Loop throught each game pad and see if anyone has pressed the 'Start' button
            if (Input.Instance.UsingGamePad)
            {
                List<PlayerIndex> connectedControllers = Input.Instance.GetConnectedControllers();
                foreach (PlayerIndex indx in connectedControllers)
                { 
                    if( Input.Instance.DidButtonJustGoDown(Microsoft.Xna.Framework.Input.Buttons.Start, indx))
                    {
                        sceneOver = true;
                        break;
                    }
                }
            }
            else
            {
                if (Input.Instance.DidKeyJustGoDown(Keys.Enter))
                {
                    sceneOver = true;
                }
            }

        }

        public virtual void ResetScreen()
        {
            sceneOver = false;
        }

        public bool SceneOver
        {
            get { return sceneOver; }
        }

    }

    #region Title Screen
    //                  ###########################################################
    //------------------#---------------------TITLE SCREEN------------------------#--------------
    //                  ###########################################################
    
    //First screen the player(s) will see
    public class TitleScreen : Screen
    {
        Vector2 skyPos, skyPosTwo, skyPosThree, mountainsPos, mountainsPosTwo, mountainsPosThree, grassPos, grassPosTwo, tankPos;
        bool initialPass = true;//Will initialize the starting positions one time on the first pass
        Rectangle tankRect = new Rectangle(0, 0, 1135, 452);
        Animation tankAnimate;
        Frame tankFrame;
        public TitleScreen(int width,int height)
            :base(width, height)
        {
            //initTextures();
            skyPos = new Vector2(0, 0);
            
        }

        public override void Draw(SpriteBatch sb)
        {          
           //base.Draw(sb);
            //Draws' the FIRST sky tile
            Texture2D texture = World.Instance.GetTexture(textureList["Sky_01"]);
            sb.Draw(texture, skyPos, Color.White);
            //Draws the SECOND sky tile
            texture = World.Instance.GetTexture(textureList["Sky_02"]);
            sb.Draw(texture, skyPosTwo, Color.White);
            //Draws the THIRD sky tile
            texture = World.Instance.GetTexture(textureList["Sky_03"]);
            sb.Draw(texture, skyPosThree, Color.White);
            //Mountains
            texture = World.Instance.GetTexture(textureList["Mountains_01"]);
            sb.Draw(texture, mountainsPos, Color.White);
            texture = World.Instance.GetTexture(textureList["Mountains_02"]);
            sb.Draw(texture, mountainsPosTwo, Color.White);
            texture = World.Instance.GetTexture(textureList["Mountains_03"]);
            sb.Draw(texture, mountainsPosThree, Color.White);
            //tank
            texture = World.Instance.GetTexture(textureList["MainScreenTank"]);
            sb.Draw(texture, tankPos, tankRect, Color.White, 0, new Vector2(0, 0), .60f, 0 , 0); 
            //Grass
            texture = World.Instance.GetTexture(textureList["GrassLoop"]);
            sb.Draw(texture, grassPos, Color.White);
            texture = World.Instance.GetTexture(textureList["GrassLoop_02"]);
            sb.Draw(texture, grassPosTwo, Color.White);
            //Title
            texture = World.Instance.GetTexture(textureList["TankdTitle"]);
            sb.Draw(texture, new Vector2(680, 150), Color.White);
            
            

        }


        public override void Update(float deltaTime)
        {
            UpdateInput();
            if (initialPass == true)
            {
                initTextures();
                initialPass = false;
            }

            //GameTime time = new GameTime();
            //base.Update(deltaTime);
            //If the screen is off no longer visible, move it to the back of the line.
            //Sky texture 1
            Texture2D texture = World.Instance.GetTexture(textureList["Sky_03"]);            
            if (skyPos.X < -World.Instance.GetTexture(textureList["Sky_01"]).Width)
                skyPos.X = skyPosThree.X + texture.Width;
            //Sky texture 2
            texture = World.Instance.GetTexture(textureList["Sky_01"]);
            if (skyPosTwo.X < -World.Instance.GetTexture(textureList["Sky_02"]).Width)
                skyPosTwo.X = skyPos.X + texture.Width;
            //Sky texture 3
            texture = World.Instance.GetTexture(textureList["Sky_02"]);
            if (skyPosThree.X < -World.Instance.GetTexture(textureList["Sky_03"]).Width)
                skyPosThree.X = skyPosTwo.X + texture.Width;
            //Mountains
            texture = World.Instance.GetTexture(textureList["Mountains_03"]);
            if (mountainsPos.X < -World.Instance.GetTexture(textureList["Mountains_01"]).Width)
                mountainsPos.X = mountainsPosThree.X + texture.Width;
            //Mountains 2
            texture = World.Instance.GetTexture(textureList["Mountains_01"]);
            if (mountainsPosTwo.X < -World.Instance.GetTexture(textureList["Mountains_02"]).Width)
                mountainsPosTwo.X = mountainsPos.X + texture.Width;
            //Mountains 3
            texture = World.Instance.GetTexture(textureList["Mountains_02"]);
            if (mountainsPosThree.X < -World.Instance.GetTexture(textureList["Mountains_03"]).Width -1)
                mountainsPosThree.X = mountainsPosTwo.X + texture.Width;
            //Grass
            texture = World.Instance.GetTexture(textureList["GrassLoop_02"]);
            if (grassPos.X < -World.Instance.GetTexture(textureList["GrassLoop"]).Width)
                grassPos.X = grassPosTwo.X + texture.Width;
            //Grass 2
            texture = World.Instance.GetTexture(textureList["GrassLoop"]);
            if (grassPosTwo.X < -World.Instance.GetTexture(textureList["GrassLoop_02"]).Width)
                grassPosTwo.X = grassPos.X + texture.Width;
            //updates the new tank animation
            tankFrame = tankAnimate.Update(deltaTime);
            tankRect = new Rectangle(tankFrame.x, tankFrame.y, tankFrame.width, tankFrame.height);

            //Scrolling the textures at various speeds.
            Vector2 speed = new Vector2(30, 0);
            Vector2 direction = new Vector2(-1, 0);
            //Sky movement
            skyPos.X += speed.X * direction.X * deltaTime; 
            skyPosTwo.X += speed.X * direction.X * deltaTime; 
            skyPosThree.X += speed.X * direction.X * deltaTime; 
            //Mountain movement
            speed = new Vector2(50, 0);
            mountainsPos.X += speed.X * direction.X * deltaTime;
            mountainsPosTwo.X += speed.X * direction.X * deltaTime;
            mountainsPosThree.X += speed.X * direction.X * deltaTime;
            //Title movement
            
            //Grass Movement
            speed = new Vector2(150, 0);
            grassPos.X += speed.X * direction.X * deltaTime;
            grassPosTwo.X += speed.X * direction.X * deltaTime;


        }

        private void UpdateInput()
        {
            // Keyboard
            if (Input.Instance.UsingKeyBoard)
            {
                if (Input.Instance.DidKeyJustGoDown(Keys.Enter))
                {
                    SoundManager.Instance.PlaySound(SoundType.BUTTON_CLICK);
                    sceneOver = true;
                }
            }
            // Gamepad
            else 
            {
                List<PlayerIndex> connectedControllers = Input.Instance.GetConnectedControllers();
                foreach (PlayerIndex indx in connectedControllers)
                {
                    if (Input.Instance.DidButtonJustGoDown(Buttons.Start, indx))
                    {
                        SoundManager.Instance.PlaySound(SoundType.BUTTON_CLICK);
                        sceneOver = true;
                    }
                }
            }
        
        }

        public void initTextures()
        {
            skyPos = new Vector2(0, 0);
            skyPosTwo = new Vector2(skyPos.X + World.Instance.GetTexture(textureList["Sky_01"]).Width, 0);
            skyPosThree = new Vector2(skyPosTwo.X + World.Instance.GetTexture(textureList["Sky_02"]).Width, 0);
            mountainsPos = new Vector2(0, 56);
            mountainsPosTwo = new Vector2(mountainsPos.X + World.Instance.GetTexture(textureList["Mountains_01"]).Width, mountainsPos.Y);
            mountainsPosThree = new Vector2(mountainsPosTwo.X + World.Instance.GetTexture(textureList["Mountains_02"]).Width-1, mountainsPos.Y);
            grassPos = new Vector2(0,720 - World.Instance.GetTexture(textureList["GrassLoop"]).Height);
            grassPosTwo = new Vector2(grassPos.X + World.Instance.GetTexture(textureList["GrassLoop"]).Width, grassPos.Y);
            tankPos = new Vector2(0, 410);
           //tank animation
            tankAnimate = new Animation("MainScreenTank", .20f, 3, 1135, 475, 0, 5, Animation.PlayDirection.FORWARD);
            tankAnimate.SetFrame(1, 0, 508, 1135, 475);
            tankAnimate.SetFrame(2, 0, 989, 1135, 475);
            tankAnimate.Direction = Animation.PlayDirection.FORWARD;

        }
    }
    #endregion 

    #region In-Game Screen
    //----------------------IN-GAME SCREEN------------------------
    //This will be the screen that players will see while playing.
    public class InGameScreen : Screen
    {
        public InGameScreen(int width, int height)
            : base(width, height)
        {

        }

    }
    #endregion

    #region Post-Game Screen
    //----------------------POST-GAME SCREEN------------------------
    //This is the screen seen after the game play is finished where statistics are displayed.
    public class PostGameScreen : Screen
    {
        int players;    // For testing only.  jwk
        

        public PostGameScreen(int width, int height)
            : base(width, height)
        {

        }

        public override void  Draw(SpriteBatch sb)
        {
 	        base.Draw(sb);

            Texture2D resultsScreen = World.Instance.GetTexture("ResultsScreen");
            sb.Draw(resultsScreen, new Vector2(0, 0), Color.White);

            Texture2D resultsButtons = World.Instance.GetTexture("ResultsButtons");
            Rectangle buttonRect = new Rectangle(0, 0, 780, 135);
            Vector2 offset = new Vector2(250, 150);
            
            for (int i = 0; i < World.Instance.GetPlayerList.Count; i++)
            {
                sb.Draw(resultsButtons, offset, buttonRect, Color.White);
                buttonRect.Y += 140;
                offset += new Vector2(0, 125);
            }

            DrawStats(sb);
        }

        public void DrawStats(SpriteBatch sb)
        {
            SpriteFont sf = World.Instance.GetFont("Results");
            List<Player> players = new List<Player>();
            players = World.Instance.GetPlayerList;

            for (int i = 1; i < players.Count; i++)
            {
                int j = i;
                int numKills = players[i].NumKills;

                while (j > 0 && (players[j - 1].NumKills < numKills))
                {
                    Player temp = players[j];
                    players[j] = players[j - 1];
                    players[j - 1] = temp;
                    j--;
                }
            }

            Vector2 offset = new Vector2(350, 170);
            for (int i = 0; i < players.Count; i++)
            {
                players[i].CalcAccuracy();
                sb.DrawString(sf, "Kills: " + players[i].NumKills, offset, players[i].PlayerColor);
                sb.DrawString(sf, "Deaths: " + players[i].NumDeaths, offset + new Vector2(0, 30), players[i].PlayerColor);
                sb.DrawString(sf, "Accuracy: " + (int)players[i].Accuracy + "%", offset + new Vector2(0, 60), players[i].PlayerColor);
                offset += new Vector2(0, 125);
            }
        }
    }
    #endregion
}
